package logic

import (
	"container/ring"
	"sync"

	"github.com/spf13/viper"
)

type offlineProcessor struct {
	n int

	//保存所有用户最近的n条消息
	recentRing *ring.Ring

	//保存某个用户的离线消息(n条)
	userRing map[string]*ring.Ring
}

var (
	mutex            sync.Mutex
	offlineprocessor *offlineProcessor
)

func GetOfflineProcessor() *offlineProcessor {
	if offlineprocessor == nil {
		mutex.Lock()
		if offlineprocessor == nil {
			offlineprocessor = NewOfflineProcessor()
		}
		mutex.Unlock()
	}
	return offlineprocessor
}

func NewOfflineProcessor() *offlineProcessor {
	n := viper.GetInt("offline-num")
	return &offlineProcessor{
		n:          n,
		recentRing: ring.New(n),
		//使用字面量语法 map[string]*ring.Ring{} 更简洁，适用于直接创建空 map 并赋值的场景；
		// 而 make 函数更灵活，支持指定初始容量，并且常用于结构体字面量初始化。
		userRing: make(map[string]*ring.Ring),
	}
}

func (o *offlineProcessor) Save(msg *Message) {
	if msg.Type != MsgTypeNormal {
		return
	}

	o.recentRing.Value = msg
	o.recentRing = o.recentRing.Next()

	for _, at := range msg.Ats {
		nickname := at[1:]
		var (
			r  *ring.Ring
			ok bool
		)

		if r, ok = o.userRing[nickname]; !ok {
			r = ring.New(o.n)
		}
		r.Value = msg
		o.userRing[nickname] = r.Next()
	}
}

func (o *offlineProcessor) Send(user *User) {
	o.recentRing.Do(func(value any) {
		if value != nil {
			user.messageChannel <- value.(*Message)
		}
	})

	if user.IsNew {
		return
	}

	if r, ok := o.userRing[user.NickName]; ok {
		r.Do(func(value any) {
			if value != nil {
				user.messageChannel <- value.(*Message)
			}
		})
	}
	delete(o.userRing, user.NickName)
}
